package com.corpgovernment.organization.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.corpgovernment.api.messageadvice.enums.MsgBizType;
import com.corpgovernment.api.organization.model.bookingrelation.UidOrgIdEntry;
import com.corpgovernment.api.organization.model.user.NameInfoBo;
import com.corpgovernment.api.organization.vo.TransferEmployeeOrgInfoVo;
import com.corpgovernment.common.base.BaseUserInfo;
import com.corpgovernment.common.base.ResourceInfo;
import com.corpgovernment.common.common.CorpBusinessException;
import com.corpgovernment.common.constant.RegularExpressionConst;
import com.corpgovernment.common.enums.CardEnum;
import com.corpgovernment.common.enums.GenderEnum;
import com.corpgovernment.common.enums.NationalityEnum;
import com.corpgovernment.common.enums.PhoneCountryCodeEnum;
import com.corpgovernment.common.utils.ABTestUtil;
import com.corpgovernment.common.utils.DateUtil;
import com.corpgovernment.common.utils.Md5Util;
import com.corpgovernment.common.utils.ObjectUtils;
import com.corpgovernment.costcenter.entity.db.MbOrgCostInfo;
import com.corpgovernment.costcenter.mapper.MbOrgCostInfoMapper;
import com.corpgovernment.job.dao.entity.db.EmployeeJobRelationDo;
import com.corpgovernment.job.dao.mapper.EmployeeJobRelationMapper;
import com.corpgovernment.job.service.JobService;
import com.corpgovernment.job.service.bo.CheckJobResultBo;
import com.corpgovernment.job.service.bo.JobBo;
import com.corpgovernment.job.service.bo.JobBoExcel;
import com.corpgovernment.organization.Bo.SyncEmployeeInfoBo;
import com.corpgovernment.organization.constant.OrganizationResponseCodeEnum;
import com.corpgovernment.organization.dataloader.BasicOssClientLoader;
import com.corpgovernment.organization.dataloader.db.MbOrgEmployeeLoader;
import com.corpgovernment.organization.entity.SyncEmployeeCallBackRequestEntity;
import com.corpgovernment.organization.entity.db.*;
import com.corpgovernment.organization.enumm.MbImportExcelRecordStatusEnum;
import com.corpgovernment.organization.enumm.OrgTypeEnum;
import com.corpgovernment.organization.enumm.ServiceErrorEnum;
import com.corpgovernment.organization.enumm.StaffStatusEnum;
import com.corpgovernment.organization.event.EmployeeActionEvent;
import com.corpgovernment.organization.mapper.MbOrgEmployeeMapper;
import com.corpgovernment.organization.mapper.MbOrgInfoMapper;
import com.corpgovernment.organization.mapper.MbOrgInfoNewMapper;
import com.corpgovernment.organization.mapper.MbUserOrgRelationMapper;
import com.corpgovernment.organization.service.*;
import com.corpgovernment.organization.util.IdCardUtil;
import com.corpgovernment.organization.util.StrUtils;
import com.corpgovernment.permission.config.RoleResourceManagerExt;
import com.corpgovernment.permission.entity.db.MbRole;
import com.corpgovernment.permission.entity.db.MbUserRole;
import com.corpgovernment.permission.service.RoleService;
import com.corpgovernment.permission.service.UserRoleService;
import com.ctrip.corp.obt.generic.core.context.RequestContext;
import com.ctrip.corp.obt.generic.core.context.TenantContext;
import com.ctrip.corp.obt.generic.event.core.EventCenter;
import com.ctrip.corp.obt.generic.exception.CommonException;
import com.ctrip.corp.obt.generic.utils.CollectionUtils;
import com.ctrip.corp.obt.generic.utils.JsonUtils;
import com.ctrip.corp.obt.generic.utils.StringUtils;
import com.excel.model.ExcelImportConfig;
import com.excel.service.excel.BizImportPreInsertResult;
import com.excel.service.excel.BizImportResult;
import com.excel.service.excel.ExcelImportProcessor;
import com.excel.service.excel.ExcelImportProcessorFactory;
import com.excel.util.TransactionUtils;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.protobuf.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.security.SecureRandom;
import java.text.MessageFormat;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static com.corpgovernment.organization.constant.OrganizationResponseCodeEnum.DOWNLOAD_EMPLOYEE_INFO_ERROR;
import static com.corpgovernment.permission.config.PermissionFilter.DATA_PERMISSION_ORG_ID_LIST;

@Service
@Slf4j
public class SyncEmployeeServiceNewImpl implements ISyncEmployeeNewService {

    @Autowired
    private IOrganizationEmployeeService organizationEmployeeService;
    @Autowired
    private IOrganizationInfoService organizationInfoService;
    @Autowired
    private IUserLoginService userLoginService;
    @Autowired
    private IMbImportExcelRecordService mbImportExcelRecordService;
    @Autowired
    private MbOrgEmployeeMapper orgEmployeeMapper;
    @Autowired
    private MbOrgEmployeeLoader mbOrgEmployeeLoader;
    @Autowired
    private IOrgUserIdCardService organizationUserIdCardService;
    @Autowired
    private IUserOrgRelationService userOrgRelationService;
    @Autowired
    private IFreshPassengerService freshPassengerService;
    @Autowired
    private FreshPassengerRelationServiceImpl freshPassengerRelationService;
    @Autowired
    private MbOrgInfoNewMapper orgInfoNewMapper;
    @Autowired
    private RoleService roleService;
    @Autowired
    private UserRoleService userRoleService;
    @Autowired
    private MbOrgCostInfoMapper orgCostInfoMapper;
    @Autowired
    private MbUserOrgRelationMapper userOrgRelationMapper;
    @Autowired
    private IPostService postService;
    @Autowired
    private MbOrgInfoMapper orgInfoMapper;
    @Autowired
    private OrganizationEmployeeServiceImpl organizationBaseService;
    @Autowired
    private EventCenter eventCenter;
    @Autowired
    @Qualifier(value = "defaultThreadPoolExecutor")
    private ThreadPoolExecutor defaultThreadPoolExecutor;
    @Autowired
    private RecordService recordService;
    @Autowired
    private RedemptionCodeService redemptionCodeService;
    @Autowired
    private ABTestUtil abTestUtil;
    @Autowired
    private MsgService msgService;
    @Autowired
    private JobService jobService;
    @Resource
    private EmployeeJobRelationMapper employeeJobRelationMapper;
    @Autowired
    private MbUserOrgRelationMapper mbUserOrgRelationMapper;
    @Autowired
    private MbOrgInfoMapper mbOrgInfoMapper;
    @Autowired
    private BasicOssClientLoader basicOssClientLoader;
    @Autowired
    private ExcelImportProcessorFactory factory;
    @Autowired
    private TransactionUtils transactionUtils;
    @Autowired
    private RoleResourceManagerExt roleResourceManagerExt;


    @Transactional(rollbackFor = Exception.class)
    @Override
    public void syncEmployeeInfo(List<SyncEmployeeInfoBo> empList, BaseUserInfo baseUserInfo, String defaultOrgId, String fileName,
                                 String fileUrl,List<SyncEmployeeCallBackRequestEntity.FailInfo> failInfoList, int totalCount,String syncTpye,Boolean checkOrgChange) {
        // 校验组织机构有没有变动
        // 前端第一次请求契约,checkOrgChange=true,校验机构是否发生变更,如果没有发生变更,继续流程
        // 如果有变更,抛出异常,前端提示组织机构变更,前端第二次发起请求checkOrgChange=false,把组织机构变更的删除角色、职级...
        this.checkOrgChange(empList,checkOrgChange);

        //向操作记录标插入数据
        MbImportExcelRecord record = recordService.insertRecord(baseUserInfo, fileName,fileUrl, empList.size());
        List<String> sucUidList;
        try {
            // 获取岗位信息
            List<JobBo> jobBoList = jobService.listAllJobBo();
            Map<String, JobBo> jobNameMap = jobBoList.stream().collect(Collectors.toMap(JobBo::getName, item -> item, (k1, k2) -> k1));
            Map<String, JobBo> jobCodeMap = jobBoList.stream().collect(Collectors.toMap(JobBo::getCode, item -> item, (k1, k2) -> k1));
            log.info("所有岗位信息: jobBoList={}", jobBoList);
            // 获取组织信息
            Map<String, String> businessCodeMap = organizationInfoService.listAll().stream().collect(Collectors.toMap(MbOrgInfo::getBusinessCode, MbOrgInfo::getOrgId, (k1, k2) -> k1));

            Map<String, List<SyncEmployeeInfoBo>> uidEmpInfoMap =
                empList.stream().collect(Collectors.groupingBy(SyncEmployeeInfoBo::getUid));
            Map<String, List<SyncEmployeeInfoBo>> phoneInfoMap =
                empList.stream()
                        .peek(m->{
                            if (m.getMobilePhone() == null) {
                                throw new CorpBusinessException(OrganizationResponseCodeEnum.PHONE_NULL);
                            }
                        })
                        .collect(Collectors.groupingBy(SyncEmployeeInfoBo::getMobilePhone));
            for (SyncEmployeeInfoBo employee : empList) {
                // 校验员工信息
                ServiceErrorEnum employeeErrorEnum = this.checkEmployeeInfo(employee);
                if (!ServiceErrorEnum.Success.getErrorCode().equals(employeeErrorEnum.getErrorCode())) {
                    failInfoList.add(addFaildInfo(SyncEmployeeInfoBo.SheetEnum.EMP.getIndex(),SyncEmployeeInfoBo.SheetEnum.EMP.getName(),employee.getLineNo(),employee.getLineNo(), employeeErrorEnum.getErrorMessage()));
                }
                // 校验证件信息
                StringBuilder cardLineNo = new StringBuilder();
                ServiceErrorEnum employeeCardErrorEnum = this.checkEmployeeCardInfo(employee, cardLineNo);
                if (!ServiceErrorEnum.Success.getErrorCode().equals(employeeCardErrorEnum.getErrorCode())) {
                    failInfoList.add(addFaildInfo(SyncEmployeeInfoBo.SheetEnum.CARD.getIndex(),SyncEmployeeInfoBo.SheetEnum.CARD.getName(),cardLineNo.toString(), employee.getLineNo(),employeeCardErrorEnum.getErrorMessage()));
                }
                checkEmployeeInfo(failInfoList, uidEmpInfoMap, phoneInfoMap, employee);
                ServiceErrorEnum employeePostErrorEnum = this.checkEmployeePostInfo(employee, defaultOrgId);
                if (!ServiceErrorEnum.Success.getErrorCode().equals(employeePostErrorEnum.getErrorCode())) {
                    failInfoList.add(addFaildInfo(SyncEmployeeInfoBo.SheetEnum.EMP.getIndex(),SyncEmployeeInfoBo.SheetEnum.EMP.getName(),employee.getLineNo(),employee.getLineNo(), employeePostErrorEnum.getErrorMessage()));
                }
                ServiceErrorEnum employeeRoleNameErrorEnum = this.checkEmployeeRoleName(employee, defaultOrgId);
                if (!ServiceErrorEnum.Success.getErrorCode().equals(employeeRoleNameErrorEnum.getErrorCode())) {
                    failInfoList.add(addFaildInfo(SyncEmployeeInfoBo.SheetEnum.EMP.getIndex(),SyncEmployeeInfoBo.SheetEnum.EMP.getName(),employee.getLineNo(),employee.getLineNo(), employeeRoleNameErrorEnum.getErrorMessage()));
                }
                ServiceErrorEnum superiorErrorEnum = this.checkSuperiorInfo(employee.getManageUid(),uidEmpInfoMap);
                if (!ServiceErrorEnum.Success.getErrorCode().equals(superiorErrorEnum.getErrorCode())) {
                    failInfoList.add(addFaildInfo(SyncEmployeeInfoBo.SheetEnum.EMP.getIndex(),SyncEmployeeInfoBo.SheetEnum.EMP.getName(),employee.getLineNo(), employee.getLineNo(),superiorErrorEnum.getErrorMessage()));
                }
                // 岗位校验
                checkEmployeeJobInfo(failInfoList, employee, jobNameMap, jobCodeMap, businessCodeMap);
            }
            log.info("failInfoList:{}", JsonUtils.toJsonString(failInfoList));
            if (CollectionUtils.isNotEmpty(failInfoList)) {
                throw new CorpBusinessException(OrganizationResponseCodeEnum.IMPORT_EMPLOYEE_EXCEL_ERROR);
            }
            empList.forEach(employee -> this.actionEmployeeInfo(employee, defaultOrgId, failInfoList,syncTpye));
            sucUidList = empList.stream().map(SyncEmployeeInfoBo::getUid).collect(Collectors.toList());

            eventCenter.post(new EmployeeActionEvent(sucUidList, defaultOrgId, EmployeeActionEvent.OpenCardAction.ACTION_EXCEL));
        } finally {
            log.info("recordProblems:{}", JsonUtils.toJsonString(failInfoList));
            recordService.recordProblems(baseUserInfo, failInfoList, totalCount, record.getId());
        }
    }

    private void checkOrgChange(List<SyncEmployeeInfoBo> employeeInfo, Boolean checkOrgChange) {
        List<String> businessCode = employeeInfo.stream().map(SyncEmployeeInfoBo::getBusinessCode).distinct().collect(Collectors.toList());
        if(CollectionUtils.isEmpty(businessCode)){
            log.info("无组织编码");
            return;
        }
        List<MbOrgInfo>  mbOrgInfoList = mbOrgInfoMapper.listByBusinessCodeWithoutBackground(businessCode);
        Map<String,String> businessCodeAndOrgIdMap= mbOrgInfoList.stream().collect(Collectors.toMap(
                MbOrgInfo::getBusinessCode,
                MbOrgInfo::getOrgId,
                (k1, k2) -> k1));
        // excel上传的用户组织关系
        Map<String,String> uidAndOrgIdMap = employeeInfo.stream().collect(Collectors.toMap(
                SyncEmployeeInfoBo::getUid,
                e-> businessCodeAndOrgIdMap.get(e.getBusinessCode()) ,
                (k1, k2) -> k1));
        List<String> uidList = employeeInfo.stream().map(SyncEmployeeInfoBo::getUid).distinct().collect(Collectors.toList());
        List<MbUserOrgRelation> mbUserOrgRelationList = mbUserOrgRelationMapper.listAllByUids(uidList);
        // DB存储的用户组织关系
        Map<String,String> uidAndOrgIdMapDB = mbUserOrgRelationList.stream().collect(Collectors.toMap(
                MbUserOrgRelation::getUid,
                MbUserOrgRelation::getOrgId,
                (k1, k2) -> k1));
        log.info("checkOrgChange,uidAndOrgIdMap:{},uidAndOrgIdMapDB:{}",JsonUtils.toJsonString(uidAndOrgIdMap),JsonUtils.toJsonString(uidAndOrgIdMapDB));
        // 判断两个Map是否完全相同
        boolean isEqual = uidAndOrgIdMap.equals(uidAndOrgIdMapDB);
        if(!isEqual && BooleanUtil.isTrue(checkOrgChange)){ // 组织机构机构发生变更 && 前端传参校验组织机构是否发生变更
            throw new CorpBusinessException(OrganizationResponseCodeEnum.ORG_CHANGE);
        }
        if(BooleanUtil.isFalse(checkOrgChange)){ // 组织机构机构发生变更 && 前端传参为false才做变更机构的操作
            handleOrgChanges(employeeInfo, uidAndOrgIdMap, uidAndOrgIdMapDB, mbUserOrgRelationList);
        }
    }

    /**
     * 把组组织机构发生变更的人员删除员工角色、岗位和职级...
     * @param employeeInfo
     * @param uidAndOrgIdMap
     * @param uidAndOrgIdMapDB
     * @param mbUserOrgRelationList
     */
    private void handleOrgChanges(List<SyncEmployeeInfoBo> employeeInfo, Map<String, String> uidAndOrgIdMap,
                                  Map<String, String> uidAndOrgIdMapDB, List<MbUserOrgRelation> mbUserOrgRelationList) {
        // 获取uidAndOrgIdMap中存在但key或value与map2中不相等的数据，以及map1中独有的数据
        List<String> diffBusinessCode = uidAndOrgIdMap.entrySet().stream()
                .filter(entry -> !uidAndOrgIdMapDB.containsKey(entry.getKey()) || !uidAndOrgIdMapDB.get(entry.getKey()).equals(entry.getValue()))
                .map(Map.Entry::getKey).collect(Collectors.toList());

        List<SyncEmployeeInfoBo> employeeInfoChange = employeeInfo.stream().filter(e -> diffBusinessCode.contains(e.getUid())).collect(Collectors.toList());
        // 处理发生机构变更的人员
        String oldOrgId = CollectionUtils.isEmpty(mbUserOrgRelationList)?null:mbUserOrgRelationList.get(0).getOrgId();
        for (SyncEmployeeInfoBo employee : employeeInfoChange) {
            List<TransferEmployeeOrgInfoVo.EmployeeOrgInfo> employeeOrgInfoList = new ArrayList<>();
            TransferEmployeeOrgInfoVo.EmployeeOrgInfo  employeeOrgInfo = new TransferEmployeeOrgInfoVo.EmployeeOrgInfo();
            employeeOrgInfo.setUid(employee.getUid());
            employeeOrgInfo.setOldOrgId(oldOrgId);
            employeeOrgInfoList.add(employeeOrgInfo);

            MbOrgInfo mbOrgInfo = organizationInfoService.findByBusinessCode(employee.getBusinessCode());
            TransferEmployeeOrgInfoVo request = new TransferEmployeeOrgInfoVo();
            request.setNewOrgId(mbOrgInfo.getOrgId());
            request.setQueryType("organizationChange");
            request.setEmployeeOrgInfoList(employeeOrgInfoList);
            try {
                // 调用批量变更部门的服务
                organizationInfoService.batchTransferEmployeeOrgInfo(request);
            } catch (Exception e) {
                log.error("handleOrgChange,request:{},变更员工部门error:{}",JsonUtils.toJsonString(request),e);
            }
        }
    }

    private void checkEmployeeJobInfo(List<SyncEmployeeCallBackRequestEntity.FailInfo> failInfoList, SyncEmployeeInfoBo employee, Map<String, JobBo> jobNameMap, Map<String, JobBo> jobCodeMap, Map<String, String> businessCodeMap) {
        String orgId = businessCodeMap.get(employee.getBusinessCode());
        String jobCode = employee.getJobCode();
        String jobName = employee.getJobName();
        String uid = employee.getUid();
        CheckJobResultBo checkJobResultBo = jobService.checkJobNameAndJobCode(jobName, jobCode, orgId, uid, jobNameMap, jobCodeMap);
        if (checkJobResultBo == null) {
            return;
        }
        if (StringUtils.isNotBlank(checkJobResultBo.getErrorMsg())) {
            failInfoList.add(addFaildInfo(SyncEmployeeInfoBo.SheetEnum.EMP.getIndex(),SyncEmployeeInfoBo.SheetEnum.EMP.getName(),employee.getLineNo(), employee.getLineNo(),checkJobResultBo.getErrorMsg()));
            return;
        }
        // 校验通过
        employee.setJobId(checkJobResultBo.getJobId());
    }

    private void checkEmployeeInfo(List<SyncEmployeeCallBackRequestEntity.FailInfo> failInfoList, Map<String, List<SyncEmployeeInfoBo>> uidEmpInfoMap, Map<String, List<SyncEmployeeInfoBo>> phoneInfoMap, SyncEmployeeInfoBo employee) {
        // 判断Uid是否重复
        List<SyncEmployeeInfoBo> uidEmployeeInfoBos = uidEmpInfoMap.get(employee.getUid());
        if (uidEmployeeInfoBos.size() > 1) {
            failInfoList.add(addFaildInfo(SyncEmployeeInfoBo.SheetEnum.EMP.getIndex(),SyncEmployeeInfoBo.SheetEnum.EMP.getName(),employee.getLineNo(), employee.getLineNo(),"Excel中存在相同Uid"));
        }
        if (StringUtils.isBlank(employee.getMobilePhone())){
            failInfoList.add(addFaildInfo(SyncEmployeeInfoBo.SheetEnum.EMP.getIndex(),SyncEmployeeInfoBo.SheetEnum.EMP.getName(),employee.getLineNo(), employee.getLineNo(),"手机号不能为空"));
        }
        if (StringUtils.isNotBlank(employee.getMobilePhone())) {
            List<SyncEmployeeInfoBo> syncEmployeeInfoBoList = phoneInfoMap.get(employee.getMobilePhone());
            if (CollectionUtils.isNotEmpty(syncEmployeeInfoBoList) && syncEmployeeInfoBoList.size() > 1) {
                failInfoList.add(addFaildInfo(SyncEmployeeInfoBo.SheetEnum.EMP.getIndex(),SyncEmployeeInfoBo.SheetEnum.EMP.getName(),employee.getLineNo(), employee.getLineNo(),"Excel中存在相同手机号"));
            }
            List<MbOrgEmployeeInfo> mbOrgEmployeeInfoList = mbOrgEmployeeLoader.selectByMobilePhoneList(Collections.singletonList(employee.getMobilePhone()));
            log.info("手机号：{}，查询结果{}", employee.getMobilePhone(), JsonUtils.toJsonString(mbOrgEmployeeInfoList));
            if(CollectionUtils.isNotEmpty(mbOrgEmployeeInfoList) && !employee.getUid().equals(mbOrgEmployeeInfoList.get(0).getUid())){
                failInfoList.add(addFaildInfo(SyncEmployeeInfoBo.SheetEnum.EMP.getIndex(),SyncEmployeeInfoBo.SheetEnum.EMP.getName(),employee.getLineNo(), employee.getLineNo(),"系统中存在相同手机号"));
            }
        }
    }


    @Override
    public List<MbOrgEmployeeInfo> findDownloadEmployeeInfo(List<String> orgIds) {
        orgIds = orgIds.stream().distinct().collect(Collectors.toList());
        Map<String, List<MbUserOrgRelation>> orgUserRelationMap = organizationBaseService.findByOrgIds(orgIds);
        List<String> uids = orgUserRelationMap.values().stream().flatMap(List::stream).map(MbUserOrgRelation::getUid).distinct().collect(Collectors.toList());
        List<Long> postId = orgUserRelationMap.values().stream().flatMap(List::stream).filter(i -> i.getPostId() != null).map(MbUserOrgRelation::getPostId).distinct().collect(Collectors.toList());
        if (CollectionUtils.isEmpty(uids)) {
            return new ArrayList<>();
        }
        Map<String, MbOrgInfo> orgInfoMap = orgInfoMapper.selectByOrgIds(orgIds).stream().collect(Collectors.toMap(MbOrgInfo::getOrgId, x -> x));
        List<MbOrgEmployeeInfo> orgEmployeeInfoList = orgEmployeeMapper.listByUids(uids);
        List<MbPostInfo> mbPostInfoList = postService.listByPostIds(postId);
        List<MbOrgCostInfo> mbOrgCostInfoList = orgCostInfoMapper.selectCostInfosByOrgId(-1, orgIds);
        Map<Long, MbPostInfo> postInfoMap = mbPostInfoList.stream().collect(Collectors.toMap(MbPostInfo::getId, e -> e, (e1, e2) -> e1));
        MbOrgCostInfo mbOrgCostInfo = CollectionUtils.isNotEmpty(mbOrgCostInfoList) ? mbOrgCostInfoList.get(0) : new MbOrgCostInfo();
        log.info("查询部门id：{},查询出来的员工信息:{},查询出来的人员身份信息:{},人员关系信息:{},postInfoMap:{}",
            orgIds, JsonUtils.toJsonString(orgEmployeeInfoList), mbPostInfoList,
                JsonUtils.toJsonString(orgUserRelationMap), JsonUtils.toJsonString(postInfoMap));

        List<MbOrgEmployeeInfo> empResults = new ArrayList<>();
        Map<String, MbOrgEmployeeInfo> employeeInfoMap = orgEmployeeInfoList.stream().collect(Collectors.toMap(MbOrgEmployeeInfo::getUid, x -> x));
        // 通过组织员工信息，构建输出结果
        List<Pair<String, String>> uidOrgIds =new ArrayList<>();
        orgUserRelationMap.values().stream().flatMap(List::stream).forEach(orgUserRelation -> {

            MbOrgEmployeeInfo mbOrgEmployeeInfo = employeeInfoMap.get(orgUserRelation.getUid());
            if (mbOrgEmployeeInfo == null) {
                return;
            }
            MbOrgInfo orgInfo = orgInfoMap.get(orgUserRelation.getOrgId());
            if (orgInfo == null) {
                return;
            }

            MbOrgEmployeeInfo empResult = new MbOrgEmployeeInfo();
            empResult.setId(mbOrgEmployeeInfo.getId());
            empResult.setBirthday(mbOrgEmployeeInfo.getBirthday());
            empResult.setEmail(mbOrgEmployeeInfo.getEmail());
            empResult.setFirstEnName(mbOrgEmployeeInfo.getFirstEnName());
            empResult.setLastEnName(mbOrgEmployeeInfo.getLastEnName());
            empResult.setGender(mbOrgEmployeeInfo.getGender());
            empResult.setMobilePhone(mbOrgEmployeeInfo.getMobilePhone());
            empResult.setUid(mbOrgEmployeeInfo.getUid());
            empResult.setName(mbOrgEmployeeInfo.getName());
            empResult.setAreaCode(mbOrgEmployeeInfo.getAreaCode());
            empResult.setNationality(mbOrgEmployeeInfo.getNationality());
            empResult.setOrgId(orgInfo.getOrgId());
            empResult.setEmployeeType(mbOrgEmployeeInfo.getEmployeeType());

            empResult.setCostName(mbOrgCostInfo.getCostCenterName());
            MbPostInfo mbPostInfo = postInfoMap.get(orgUserRelation.getPostId());
            if (mbPostInfo != null) {
                empResult.setPostName(mbPostInfo.getName());
                empResult.setPostId(mbPostInfo.getId());
            }
            empResult.setOrgName(OrgTypeEnum.D.getCode().equalsIgnoreCase(orgInfo.getOrgType()) ? orgInfo.getName() : null);
            empResult.setCompanyName(findCompanyName(orgInfo));
            empResult.setManageUid(orgUserRelation.getManageUid());
            uidOrgIds.add(Pair.of(empResult.getUid(), orgUserRelation.getOrgId()));
            empResults.add(empResult);
        });

        // 查询员工的角色,每500个一组查询
        Map<Pair<String, String>, List<Long>> empRoleMap = Maps.newHashMapWithExpectedSize(uidOrgIds.size());
        List<CompletableFuture<Map<Pair<String, String>, List<Long>>>> features =
            Lists.partition(uidOrgIds, 500).stream()
                .map(uidOrgIdGroup -> CompletableFuture.supplyAsync(
                    () -> roleService.batchSearchUserRoleIdByUidAndOrgId(uidOrgIdGroup), defaultThreadPoolExecutor))
                .collect(Collectors.toList());
        try {
            CompletableFuture.allOf(features.toArray(new CompletableFuture[] {})).get(15, TimeUnit.SECONDS);
            for (CompletableFuture<Map<Pair<String, String>, List<Long>>> feature : features) {
                empRoleMap.putAll(feature.get());
            }
        } catch (Exception e) {
            log.error("导出员工信息查询员工角色出现异常", e);
            throw new CommonException(DOWNLOAD_EMPLOYEE_INFO_ERROR);
        }

        // 查询角色id对应角色名
        Map<Long, String> roleIdNameMap = roleService
            .batchSearchRoleName(empRoleMap.values().stream().flatMap(Collection::stream).collect(Collectors.toSet()));

        for (MbOrgEmployeeInfo empResult : empResults) {
            List<Long> roleIds = empRoleMap.getOrDefault(Pair.of(empResult.getUid(), empResult.getOrgId()), Collections.emptyList());
            String roleName = roleIds.stream().map(roleIdNameMap::get).filter(Objects::nonNull).collect(Collectors.joining(","));
            // 设置角色名
            empResult.setRoleName(roleName);
            // 设置组织编码
            empResult.setOrgId(orgInfoMap.get(empResult.getOrgId()).getBusinessCode());
        }

        return empResults;
    }

    @Override
    public List<MbOrgEmployeeInfo> findDownloadOrgsEmployeeInfo(List<String> orgIds) {
        Map<String, List<MbUserOrgRelation>> orgUidsMap = organizationBaseService.findByOrgIds(orgIds);
        if (CollectionUtils.isEmpty(orgUidsMap)) {
            return new ArrayList<>();
        }
        List<MbOrgEmployeeInfo> response = new ArrayList<>();

        List<MbPostInfo> mbPostInfoList = postService.listByOrgIds(orgIds);
        Map<Long, MbPostInfo> postInfoMap = Optional.ofNullable(mbPostInfoList).orElse(new ArrayList<>()).stream().collect(Collectors.toMap(MbPostInfo::getId, e -> e, (e1, e2) -> e1));

        List<MbOrgInfo> mbOrgInfoList = orgInfoMapper.selectByOrgIds(orgIds);
        Map<String, MbOrgInfo> orgInfoMap = mbOrgInfoList.stream().collect(Collectors.toMap(MbOrgInfo::getOrgId, e -> e, (e1, e2) -> e1));

        orgUidsMap.forEach((orgId, userOrgRelations) -> {
            List<MbOrgEmployeeInfo> orgEmployeeInfoList = orgEmployeeMapper.listByUids(userOrgRelations.stream().map(MbUserOrgRelation::getUid).collect(Collectors.toList()));
            if (CollectionUtils.isEmpty(orgEmployeeInfoList)) {
                return;
            }

            Map<String, MbUserOrgRelation> userOrgRelationMap = userOrgRelations.stream().collect(Collectors.toMap(MbUserOrgRelation::getUid, e -> e, (e1, e2) -> e1));

            List<MbOrgCostInfo> mbOrgCostInfoList = orgCostInfoMapper.selectCostInfosByOrgId(-1, Lists.newArrayList(orgId));
            MbOrgCostInfo mbOrgCostInfo = CollectionUtils.isNotEmpty(mbOrgCostInfoList) ? mbOrgCostInfoList.get(0) : new MbOrgCostInfo();
            for (MbOrgEmployeeInfo mbOrgEmployeeInfo : orgEmployeeInfoList) {
                mbOrgEmployeeInfo.setCostName(mbOrgCostInfo.getCostCenterName());

                if (userOrgRelationMap.containsKey(mbOrgEmployeeInfo.getUid())) {
                    MbPostInfo mbPostInfo = Optional.ofNullable(postInfoMap.get(userOrgRelationMap.get(mbOrgEmployeeInfo.getUid()).getPostId())).orElse(new MbPostInfo());
                    mbOrgEmployeeInfo.setPostName(mbPostInfo.getName());
                }

                MbOrgInfo mbOrgInfo = orgInfoMap.get(orgId);
                mbOrgEmployeeInfo.setOrgName(OrgTypeEnum.D.getCode().equalsIgnoreCase(mbOrgInfo.getOrgType()) ? mbOrgInfo.getName() : null);
                mbOrgEmployeeInfo.setCompanyName(findCompanyName(mbOrgInfo));
                List<MbRole> mbRoleList = roleService.findByUidAndOrgId(mbOrgEmployeeInfo.getUid(), mbOrgEmployeeInfo.getOrgId());
                StringBuffer sb = new StringBuffer();
                Optional.ofNullable(mbRoleList).orElse(new ArrayList<>()).stream().forEach(item -> sb.append(item.getName()).append(", "));
                if (sb.length() > 0) {
                    sb.deleteCharAt(sb.length() - 1);
                }
                mbOrgEmployeeInfo.setRoleName(sb.toString());
                response.add(mbOrgEmployeeInfo);
            }
        });

        return response;
    }

    @Override
    public <PREINSERT> void handleEmployImport(MultipartFile file, BaseUserInfo baseUserInfo, String defaultOrgId, String syncTpye,Boolean checkOrgChange) throws Exception {

        // 上传excel资源到阿里云
        String fileUrl = basicOssClientLoader.putPrivateObject(file);
        //向操作记录标插入数据
        MbImportExcelRecord record = recordService.insertRecord(baseUserInfo, file.getOriginalFilename(), fileUrl, 0);

        try {
            ExcelImportProcessor processor = factory.getMessageHandler("employ_"+syncTpye+"_v1");
            if (processor != null) {

                BizImportResult<SyncEmployeeCallBackRequestEntity.FailInfo, SyncEmployeeInfoBo> excelDataRes = processor.assembleListFromExcel(record,file);

                List<SyncEmployeeInfoBo> dataList = excelDataRes.getData();

                List<SyncEmployeeCallBackRequestEntity.FailInfo> errorList = new ArrayList<>();

                if(CollectionUtils.isEmpty(dataList)){
                    // 记录错误日志 并更新记录状态
                    SyncEmployeeCallBackRequestEntity.FailInfo errorLog = new SyncEmployeeCallBackRequestEntity.FailInfo();
                    errorLog.setMainLineNo("");
                    errorLog.setLineNo("");
                    errorLog.setSheetName(SyncEmployeeInfoBo.SheetEnum.EMP.getName());
                    errorLog.setSheetIndex(SyncEmployeeInfoBo.SheetEnum.EMP.getIndex());
                    errorLog.setFailReason(OrganizationResponseCodeEnum.FILE_IS_NULL.message());
                    errorList.add(errorLog);
                    recordService.recordProblems(baseUserInfo, errorList, dataList.size(), record.getId());
                    throw new CorpBusinessException(OrganizationResponseCodeEnum.FILE_IS_NULL);
                }

                BizImportResult<SyncEmployeeCallBackRequestEntity.FailInfo, SyncEmployeeInfoBo> checkExcelDataRes =  processor.checkExcelData(dataList);

                // 校验组织机构有没有变动
                // 前端第一次请求契约,checkOrgChange=true,校验机构是否发生变更,如果没有发生变更,继续流程
                // 如果有变更,抛出异常,前端提示组织机构变更,前端第二次发起请求checkOrgChange=false,把组织机构变更的删除角色、职级...
                if(SyncEmployeeInfoBo.SyncType.UPDATE.getDesc().equals(syncTpye)){
                    checkOrgChange(dataList,checkOrgChange);
                }

                BizImportPreInsertResult<SyncEmployeeCallBackRequestEntity.FailInfo, SyncEmployeeInfoBo, PREINSERT> checkDbDataRes =  processor.checkDbDataWithPreInsert(dataList);

                BizImportResult<SyncEmployeeCallBackRequestEntity.FailInfo, SyncEmployeeInfoBo> checkDataPermissionRes =  processor.checkDataPermission(dataList);

                if(excelDataRes != null) {
                    errorList.addAll(excelDataRes.getError());
                }
                if(checkExcelDataRes != null) {
                    errorList.addAll(checkExcelDataRes.getError());
                }
                if(checkDbDataRes != null) {
                    errorList.addAll(checkDbDataRes.getError());
                }
                if(checkDataPermissionRes != null) {
                    errorList.addAll(checkDataPermissionRes.getError());
                }

                if(CollectionUtil.isNotEmpty(errorList)){
                    // 有报错且全量回滚
                    // 记录错误日志 并更新记录状态
                    recordService.recordProblems(baseUserInfo, errorList, dataList.size(), record.getId());
                    throw new CorpBusinessException(OrganizationResponseCodeEnum.IMPORT_EMPLOYEE_EXCEL_ERROR);
                }

                // 最后开启整体事务插入，防止脏数据写入后未删除
                transactionUtils.runInTransaction(() -> {

                    if(checkDbDataRes != null && CollectionUtils.isNotEmpty(checkDbDataRes.getPreInsert())) {
                        processor.preWriteDB(dataList,checkDbDataRes.getPreInsert());
                    }

                    dataList.forEach(employee -> this.actionEmployeeInfo(employee, defaultOrgId, errorList, syncTpye));
                    List<String> sucUidList = dataList.stream().map(SyncEmployeeInfoBo::getUid).collect(Collectors.toList());

                    // 记录错误日志 并更新记录状态
                    recordService.recordProblems(baseUserInfo, errorList, dataList.size(), record.getId());

                    eventCenter.post(new EmployeeActionEvent(sucUidList, defaultOrgId, EmployeeActionEvent.OpenCardAction.ACTION_EXCEL));

                    // 新增员工时，在此执行发送短信
                });

            }
        }catch (CorpBusinessException e){
            throw e;
        }catch (Exception e){
            String status = MbImportExcelRecordStatusEnum.F.getDealCode();
            MbImportExcelRecord importExcelRecord = new MbImportExcelRecord();
            importExcelRecord.setId(record.getId());
            importExcelRecord.setUid(baseUserInfo.getUid());
            importExcelRecord.setTotalCount(0);
            importExcelRecord.setCheckPassedCount(0);
            importExcelRecord.setFailCount(0);
            importExcelRecord.setStatus(status);
            mbImportExcelRecordService.updateRecord(importExcelRecord);
            throw e;
        }


    }

    @Override
    public List<MbOrgUserIdcard> findOrgUserIdCard(List<String> uids) {
        if (CollectionUtils.isEmpty(uids)) {
            return Lists.newArrayList();
        }
        return organizationUserIdCardService.batchFindByUids(uids);
    }

    private String findCompanyName(MbOrgInfo mbOrgInfo) {
        if (mbOrgInfo == null) {
            return null;
        }
        if (OrgTypeEnum.G.getCode().equalsIgnoreCase(mbOrgInfo.getOrgType()) || OrgTypeEnum.C.getCode().equalsIgnoreCase(mbOrgInfo.getOrgType())) {
            return mbOrgInfo.getName();
        }
        MbOrgInfo parentOrgInfo = orgInfoMapper.selectOneByOrgId(mbOrgInfo.getParentId());
        return findCompanyName(parentOrgInfo);
    }

    public SyncEmployeeCallBackRequestEntity.FailInfo addFaildInfo(Integer sheetIndex,String sheetName,String lineNo, String mainLineNo,String message) {
        SyncEmployeeCallBackRequestEntity.FailInfo failInfo = new SyncEmployeeCallBackRequestEntity.FailInfo();
        failInfo.setSheetIndex(sheetIndex);
        failInfo.setSheetName(sheetName);
        failInfo.setLineNo(lineNo);
        failInfo.setMainLineNo(mainLineNo);
        failInfo.setFailReason(message);
        return failInfo;
    }

    public ServiceErrorEnum checkEmployeeInfo(SyncEmployeeInfoBo employee) {
        //员工ID、员工名字、手机国家码、手机号，性别，其中之一为空
        if (employee == null
                || StringUtils.isEmpty(employee.getUid())
                || StringUtils.isEmpty(employee.getName())
                || StringUtils.isEmpty(employee.getCountryCode())
                || StringUtils.isEmpty(employee.getMobilePhone())
                || StringUtils.isEmpty(employee.getGender())) {
            return ServiceErrorEnum.SyncHumanResources_SyncEmployeeInfo_EmptyBasicInfo_Failure;
        }
        // 校验用户ID
        if(Objects.nonNull(employee.getEmpId())) {
            MbOrgEmployeeInfo byId = orgEmployeeMapper.findById(employee.getEmpId());
            if (Objects.isNull(byId)) {
                return ServiceErrorEnum.SyncHumanResources_SyncEmployeeInfo_FIND_EMP_BY_ID_Failure;
            }
            if (!byId.getUid().equals(employee.getUid())) {
                return ServiceErrorEnum.SyncHumanResources_SyncEmployeeInfo_FIND_EMP_UID_MISMATCH_Failure;
            }
        }

        if (StringUtils.isNotBlank(employee.getBusinessCode())){
            MbOrgInfo mbOrgInfo = organizationInfoService.findByBusinessCode(employee.getBusinessCode());
            if (Objects.isNull(mbOrgInfo)){
                return ServiceErrorEnum.SyncHumanResources_SyncEmployeeInfo_company_Null_Failure;
            }
        }

        //校验证件
        if (CollectionUtils.isEmpty(employee.getCardInfoList())) {
            return ServiceErrorEnum.SyncHumanResources_SyncEmployeeInfo_EmptyCardType_Failure;
        }
        //手机区号
        PhoneCountryCodeEnum phoneCountryCodeEnum = StringUtils.isEmpty(employee.getCountryCode()) ? null : PhoneCountryCodeEnum.getByCountryCode(employee.getCountryCode());
        if (phoneCountryCodeEnum == null) {
            employee.setCountryCode(PhoneCountryCodeEnum.CN.getCountryCode());
        }
        //邮箱格式
        if (!StringUtils.isEmpty(employee.getEmail()) && !employee.getEmail().matches(RegularExpressionConst.MAIL)) {
            return ServiceErrorEnum.SyncHumanResources_SyncEmployeeInfo_ContactInfo_EmailFormat_Failure;
        }
        //手机号码
        Pattern p = Pattern.compile(RegularExpressionConst.PHONE);
        if (!StringUtils.isEmpty(employee.getMobilePhone()) && !p.matcher(employee.getMobilePhone()).find()) {
            return ServiceErrorEnum.SyncHumanResources_SyncEmployeeInfo_ContactInfo_PhoneFormat_Failure;
        }

        //没传密码取值为手机后8位
        String mobilePhone = employee.getMobilePhone();
        employee.setPassword(Optional.ofNullable(employee.getPassword()).orElse(buildNewPwd(mobilePhone)));

        //生日格式
        if (StringUtils.isNotBlank(employee.getBirthday())) {
            Date birth = DateUtil.stringToDate(employee.getBirthday(), DateUtil.DF_YMD);
            if (birth == null) {
                return ServiceErrorEnum.SyncHumanResources_SyncEmployeeInfo_ErrorBirthday_Failure;
            }
        }

        // 性别超出赋值范围，不赋值则默认男性
        employee.setGender(Optional.ofNullable(employee.getGender()).orElse(GenderEnum.M.getCode()));
        if (!StrUtils.In(employee.getGender(), GenderEnum.F.getCode(), GenderEnum.M.getCode())) {
            return ServiceErrorEnum.SyncHumanResources_SyncEmployeeInfo_ErrorGender_Failure;
        }

        // 国籍超出赋值范围，不赋值则默认中国大陆
        NationalityEnum nation = NationalityEnum.getByCode(Optional.ofNullable(employee.getNationality()).orElse(NationalityEnum.CN.getCode()));
        if (nation == null) {
            return ServiceErrorEnum.SyncHumanResources_SyncEmployeeInfo_ErrorNationality_Failure;
        }

        // 按前端格式赋值 CN|中国大陆
        employee.setNationality(String.join("|", nation.getCode(), nation.getDesc()));
        employee.setNationCode(nation.getCode());
        employee.setNationName(nation.getDesc());
        return ServiceErrorEnum.Success;
    }

    private String buildNewPwd(String phoneNum) {
        String newLast5 = phoneNum.substring(phoneNum.length() - 5);
        // 生成包含字母的随机数
        SecureRandom random = new SecureRandom();
        byte[] bytes = new byte[4];
        random.nextBytes(bytes);
        String randomStr = Base64.getEncoder().encodeToString(bytes).substring(0, 4);
        return  newLast5 + randomStr;
    }

    public ServiceErrorEnum checkEmployeeCardInfo(SyncEmployeeInfoBo employee, StringBuilder cardLineNo) {
        for (SyncEmployeeInfoBo.SyncEmployeeCardInfoBo cardType : employee.getCardInfoList()) {
            cardLineNo.delete(0, cardLineNo.length());
            cardLineNo.append(cardType.getLineNo());
            // 卡片基本信息不能为空
            if (StringUtils.isEmpty(cardType.getCardNo()) || cardType == null || cardType.getCardType() == null) {
                return ServiceErrorEnum.SyncHumanResources_SyncEmployeeInfo_EmptyCardType_Failure;
            }

            // 证件类型超出赋值范围
            if (Objects.isNull(CardEnum.getByName(cardType.getCardType()))) {
                return ServiceErrorEnum.SyncHumanResources_SyncEmployeeInfo_OutOfCardType_Failure;
            }
            cardType.setCardType(CardEnum.getByName(cardType.getCardType()).getType());

            // 证件类型为护照或国际海员证时，证件签发国是否为空，为空则不可上传，失败原因：证件签发国不可为空；
            boolean passportOrInternalSeafarer = CardEnum.PASSPROT.getType().equals(cardType.getCardType()) ||
                    CardEnum.INTERNAL_SEAFARER_CARD.getType().equals(cardType.getCardType());
            if (passportOrInternalSeafarer && StringUtils.isBlank(cardType.getPlaceOfIssue())) {
                return ServiceErrorEnum.SyncHumanResources_SyncEmployeeInfo_EmptyCardTypePlaceOfIssue_Failure;
            }

            //护照、军人证、回乡证、台胞证、港澳通行证、旅行证、外国人永久居留身份证、其他时证件到期日期不可为空，为空则不可上传
            // 失败原因：证件到期日期不可为空；
            boolean needTimeLimitVerify = CardEnum.PASSPROT.getType().equals(cardType.getCardType()) ||
                    CardEnum.SOLDIER_CARD.getType().equals(cardType.getCardType()) ||
                    CardEnum.RETURN_HOME_CARD.getType().equals(cardType.getCardType()) ||
                    CardEnum.TAIWAN_CARD.getType().equals(cardType.getCardType()) ||
                    CardEnum.GANGAO_CARD.getType().equals(cardType.getCardType()) ||
                    CardEnum.TRAVEL_CARD.getType().equals(cardType.getCardType()) ||
                    CardEnum.FOREIGNER_LIVE_CARD.getType().equals(cardType.getCardType()) ||
                    CardEnum.ELSE.getType().equals(cardType.getCardType());
            if (needTimeLimitVerify && StringUtils.isBlank(cardType.getTimeLimit())) {
                return ServiceErrorEnum.SyncHumanResources_SyncEmployeeInfo_EmptyCardTypeTimeLimit_Failure;
            }

            // 证件有效期超出日期范围
            if (StringUtils.isNotBlank(cardType.getTimeLimit())) {
                Date birth = DateUtil.stringToDate(cardType.getTimeLimit(), DateUtil.DF_YMD);
                if (birth == null) {
                    return ServiceErrorEnum.SyncHumanResources_SyncEmployeeInfo_ErrorCardTypeTimeLimit_Failure;
                }
            }

            //增加身份证校验
            if (Objects.equals(CardEnum.ID_CARD.getType(), cardType.getCardType())) {
                //身份证正则
                if (!cardType.getCardNo().matches(RegularExpressionConst.CARD)) {
                    return ServiceErrorEnum.SyncHumanResources_SyncEmployeeInfo_ContactInfo_IdCard_Failure;
                }
                //身份证和生日
                if (!IdCardUtil.validDate(cardType.getCardNo(), employee.getBirthday())) {
                    return ServiceErrorEnum.SyncHumanResources_SyncEmployeeInfo_ContactInfo_IdCard_Birthday_Failure;
                }

                //以身份证性别为准 覆盖处理
                String sex = IdCardUtil.getSex(cardType.getCardNo());
                employee.setGender("男".equals(sex) ? GenderEnum.M.getCode() : GenderEnum.F.getCode());

            }
        }
        return ServiceErrorEnum.Success;
    }

    /**
     * 校验组织/职级
     *
     * @param employee
     * @return
     */
    public ServiceErrorEnum checkEmployeePostInfo(SyncEmployeeInfoBo employee, String orgId) {
        String businessCode = employee.getBusinessCode();
        if(StringUtils.isBlank(businessCode)){
            return ServiceErrorEnum.SyncHumanResources_SyncEmployeeInfo_BUSINESS_IS_NULL;
        }
        String postName = employee.getPostName();
        MbPostInfo postOrgInfoById = null;
        Long postId = employee.getPostId();
        MbOrgInfo thisItem = organizationInfoService.findByBusinessCode(businessCode);
        if(ObjectUtil.isNull(thisItem) || ObjectUtil.isNull(thisItem.getOrgId())){
            return ServiceErrorEnum.SyncHumanResources_SyncEmployeeInfo_BUSINESS_IS_NULL;
        }
        // 获取当前excel填写的组织编码 的最近一级的公司信息 -匹配职级
        MbOrgInfo mbOrgInfo = organizationInfoService.findFirstCompany(thisItem.getOrgId());
        if(Objects.nonNull(postId)){
            postOrgInfoById = postService.find(postId);
            if(Objects.isNull(postOrgInfoById)){
                log.info("当前职级别ID无匹配结果,职级ID:{}",postId);
                return ServiceErrorEnum.SyncHumanResources_SyncEmployeeInfo_Post_Id_Null_Failure;
            }
            if (!Objects.equals(postOrgInfoById.getOrgId(), mbOrgInfo.getOrgId())) {
                return ServiceErrorEnum.SyncHumanResources_SyncEmployeeInfo_POST_IS_NOT_IN;
            }
            employee.setPostName(postOrgInfoById.getName());
        }
        if (StringUtils.isNotBlank(postName) && postOrgInfoById == null) {
            List<MbPostInfo> postInfos = postService.findByName(postName);
            if (CollectionUtils.isEmpty(postInfos)) {
                employee.setPostId(null);
                employee.setPostName(null);
                log.info("当前职级名称不存在或者存在多个，无法关联:{}",employee.getPostId());
                return ServiceErrorEnum.SyncHumanResources_SyncEmployeeInfo_PostOrgInfo_Failure;
            }else {
                MbPostInfo postInfo = selectPostByOrgId(postInfos, mbOrgInfo.getOrgId());
                if (Objects.isNull(postInfo)) {
                    return ServiceErrorEnum.SyncHumanResources_SyncEmployeeInfo_PostOrgInfo_Failure;
                }
                employee.setPostId(postInfo.getId());
            }
        }
        return ServiceErrorEnum.Success;
    }

    public ServiceErrorEnum checkEmployeeRoleName(SyncEmployeeInfoBo employee, String orgId) {
        String businessCode = employee.getBusinessCode();
        if(StringUtils.isBlank(businessCode)){
            return ServiceErrorEnum.SyncHumanResources_SyncEmployeeInfo_BUSINESS_IS_NULL;
        }
        if (StringUtils.isNotBlank(employee.getRoleName())) {
            MbOrgInfo thisItem = organizationInfoService.findByBusinessCode(businessCode);
            if(ObjectUtil.isNull(thisItem) || ObjectUtil.isNull(thisItem.getOrgId())){
                return ServiceErrorEnum.SyncHumanResources_SyncEmployeeInfo_BUSINESS_IS_NULL;
            }
            // 获取当前excel填写的组织编码 的最近一级的公司信息 -匹配职级
            MbOrgInfo mbOrgInfo = organizationInfoService.findFirstCompany(thisItem.getOrgId());
            List<MbRole> mbRoles = roleService.listCorpRoles(mbOrgInfo.getOrgId());
            if (CollectionUtils.isNotEmpty(mbRoles)) {
                long count = mbRoles.stream().filter(item -> item.getName().equalsIgnoreCase(employee.getRoleName())).count();
                if (count < 1) {
                    return ServiceErrorEnum.SyncHumanResources_SyncEmployeeInfo_RoleName_Failure;
                }
            }
        }
        return ServiceErrorEnum.Success;
    }


    public ServiceErrorEnum checkSuperiorInfo(String superiorUid, Map<String, List<SyncEmployeeInfoBo>> uidInfoMap) {
        if (StringUtils.isNotBlank(superiorUid)) {
            MbOrgEmployeeInfo employeeInfo = organizationEmployeeService.findByUid(superiorUid);
            //数据库中和excel表中不存在时报错
            if (Objects.isNull(employeeInfo)) {
                List<SyncEmployeeInfoBo> superiorInfo = uidInfoMap.get(superiorUid);
                if (CollectionUtils.isEmpty(superiorInfo)) {
                    return ServiceErrorEnum.SYNCHUMANRESOURCES_SYNCEMPLOYEEINFO_SUPERIOR_FAILURE;
                }
            }
        }
        return ServiceErrorEnum.Success;
    }

    @Transactional(rollbackFor = Exception.class)
    public void actionEmployeeInfo(SyncEmployeeInfoBo employee, String orgId, List<SyncEmployeeCallBackRequestEntity.FailInfo> failInfoList,String syncTpye) {
        MbOrgEmployeeInfo orgEmployeeInfo = organizationEmployeeService.findAllByUid(employee.getUid());
        // uid相同做修改处理
        if(orgEmployeeInfo == null && SyncEmployeeInfoBo.SyncType.UPDATE.getDesc().equals(syncTpye)){
            failInfoList.add(addFaildInfo(SyncEmployeeInfoBo.SheetEnum.EMP.getIndex(),SyncEmployeeInfoBo.SheetEnum.EMP.getName(),employee.getLineNo(), employee.getLineNo(),OrganizationResponseCodeEnum.UID_DONT_EXISTS.message()));
            throw new CorpBusinessException(OrganizationResponseCodeEnum.UID_DONT_EXISTS);
        }
        if (orgEmployeeInfo != null && SyncEmployeeInfoBo.SyncType.UPDATE.getDesc().equals(syncTpye)) {
            if (orgEmployeeInfo.getMobilePhone().equals(employee.getMobilePhone())) {

                checkUidExist(employee, failInfoList);
                // check dataPermission
                checkDataPermission(employee, failInfoList);

                // 更新员工数据
                updateOrgEmployeeInfo(employee, orgEmployeeInfo);
                // 先删有效证件后增加有效证件
                insertCardInfo(employee, failInfoList);
                // 更新员工组织信息和职级信息和上级信息
                updateOrgInfoAndPost(employee);
                // 更新登陆人信息
                updateUserLogin(employee);
                // 绑定角色
                String businessCode = employee.getBusinessCode();
                if (StringUtils.isNotBlank(employee.getRoleName())) {
                    MbOrgInfo thisItem = organizationInfoService.findByBusinessCode(businessCode);
                    // 获取当前excel填写的组织编码 的最近一级的公司信息 -匹配角色
                    MbOrgInfo mbOrgInfo = organizationInfoService.findFirstCompany(thisItem.getOrgId());
                    List<MbRole> mbRoles = roleService.listCorpRoles(mbOrgInfo.getOrgId());
                    if (CollectionUtils.isNotEmpty(mbRoles)) {
                        Optional<MbRole> first = mbRoles.stream()
                                .filter(item -> item.getName().equalsIgnoreCase(employee.getRoleName())).findFirst();
                        if (first.isPresent()) {
                            MbRole mbRole = first.get();
                            UidOrgIdEntry identity = new UidOrgIdEntry();
                            identity.setUid(employee.getUid());
                            identity.setOrgId(thisItem.getOrgId());
                            List<MbUserRole> mbUserRoleList = userRoleService.getUserRoleByUid(employee.getUid());
                            if(CollectionUtils.isNotEmpty(mbUserRoleList)){
                                Long roleId = mbUserRoleList.get(0).getId();
                                userRoleService.insertOrUpdate(roleId, identity, mbRole.getId());
                                roleResourceManagerExt.delResource(String.valueOf(roleId));
                            }else {
                                userRoleService.insertOrUpdate(null, identity, mbRole.getId());
                            }

                        }
                    }
                }
                // 更新岗位
                employeeJobRelationMapper.createOrUpdate(EmployeeJobRelationDo.builder().uid(employee.getUid()).jobId(employee.getJobId()).build());
                return ;
            } else {
                failInfoList.add(addFaildInfo(SyncEmployeeInfoBo.SheetEnum.EMP.getIndex(),SyncEmployeeInfoBo.SheetEnum.EMP.getName(),employee.getLineNo(), employee.getLineNo(),OrganizationResponseCodeEnum.EMPLOYEE_UID_EXIST.message()));
                throw new CorpBusinessException(OrganizationResponseCodeEnum.EMPLOYEE_UID_EXIST);
            }
        }

        //checkUidFromDb(employee, failInfoList);

        //checkPhoneFromDb(employee, failInfoList);

        // 新增员工数据
        insertOrgEmployeeInfo(employee);
        // 绑定兑换码
        redemptionCodeService.bindRedemptionCode(employee.getUid(), employee.getName());
        // 新增登录信息 + 发送短信
        insertUserLoginWithSms(employee);
        // 查询导入组织信息
        MbOrgInfo orgInfo = getOrgInfoByOrgId(orgId);
        // 将UID和ORG_ID关联起来
        if (StringUtils.isNotBlank(employee.getBusinessCode())) {
            updateOrgInfoAndPost(employee);
        } else {
            insertUserOrgRelation(employee, orgInfo, employee.getPostId());
        }
        // 先删后增用户新鲜度数据
        insertFreshPassenger(employee, orgInfo);
        // 先删有效证件后增加有效证件
        insertCardInfo(employee, failInfoList);
        // 绑定角色
        String businessCode = employee.getBusinessCode();
        if (StringUtils.isNotBlank(employee.getRoleName())) {
            MbOrgInfo thisItem = organizationInfoService.findByBusinessCode(businessCode);
            // 获取当前excel填写的组织编码 的最近一级的公司信息 -匹配角色
            MbOrgInfo mbOrgInfo = organizationInfoService.findFirstCompany(thisItem.getOrgId());
            List<MbRole> mbRoles = roleService.listCorpRoles(mbOrgInfo.getOrgId());
            if (CollectionUtils.isNotEmpty(mbRoles)) {
                Optional<MbRole> first = mbRoles.stream()
                    .filter(item -> item.getName().equalsIgnoreCase(employee.getRoleName())).findFirst();
                if (first.isPresent()) {
                    MbRole mbRole = first.get();
                    UidOrgIdEntry identity = new UidOrgIdEntry();
                    identity.setUid(employee.getUid());
                    identity.setOrgId(thisItem.getOrgId());
                    userRoleService.insertOrUpdate(null, identity, mbRole.getId());
                }
            }
        }
        //11
        // 新增岗位
        employeeJobRelationMapper.createOrUpdate(EmployeeJobRelationDo.builder().uid(employee.getUid()).jobId(employee.getJobId()).build());


    }

    private void checkUidExist(SyncEmployeeInfoBo employee, List<SyncEmployeeCallBackRequestEntity.FailInfo> failInfoList) {
        MbOrgEmployeeInfo record = new MbOrgEmployeeInfo();
        record.setUid(employee.getUid());
        MbOrgEmployeeInfo oldEmployeeInfo = mbOrgEmployeeLoader.selectOneByRecord(record);
        if (oldEmployeeInfo == null) {
            failInfoList.add(addFaildInfo(SyncEmployeeInfoBo.SheetEnum.EMP.getIndex(),SyncEmployeeInfoBo.SheetEnum.EMP.getName(), employee.getLineNo(), employee.getLineNo(),OrganizationResponseCodeEnum.UID_DONT_EXISTS.message()));
            throw new CorpBusinessException(OrganizationResponseCodeEnum.UID_DONT_EXISTS);
        }
    }

    private void checkDataPermission(SyncEmployeeInfoBo employee, List<SyncEmployeeCallBackRequestEntity.FailInfo> failInfoList) {
        List<MbUserOrgRelation> mbUserOrgRelations = userOrgRelationMapper.listByUids(Collections.singletonList(employee.getUid()));
        // excel uid映射的orgId
        List<String> uidOrgIds = mbUserOrgRelations.stream()
                .map(MbUserOrgRelation::getOrgId)
                .filter(id -> StringUtils.isNotBlank(id))
                .distinct()
                .collect(Collectors.toList());
        if(CollectionUtils.isNotEmpty(uidOrgIds)){
            List<String> orgIds = (List<String>) RequestContext.getCurrentContext().getContextParams(DATA_PERMISSION_ORG_ID_LIST);
            log.info("登录用户拥有的部门权限为{},上传excel员工编号所属的部门为{}",JsonUtils.toJsonString(orgIds),uidOrgIds.get(0));
            if(CollectionUtils.isNotEmpty(orgIds) && !orgIds.contains(uidOrgIds.get(0))){
                failInfoList.add(addFaildInfo(SyncEmployeeInfoBo.SheetEnum.EMP.getIndex(),SyncEmployeeInfoBo.SheetEnum.EMP.getName(), employee.getLineNo(), employee.getLineNo(),OrganizationResponseCodeEnum.UID_DONT_PERMISSION.message()));
                throw new CorpBusinessException(OrganizationResponseCodeEnum.UID_DONT_PERMISSION);
            }
        }
    }

    private void checkPhoneFromDb(SyncEmployeeInfoBo employee, List<SyncEmployeeCallBackRequestEntity.FailInfo> failInfoList) {
        MbOrgEmployeeInfo record = new MbOrgEmployeeInfo();
        record.setIsBackground(false);
        record.setMobilePhone(employee.getMobilePhone());
        record.setAreaCode(employee.getCountryCode());
        record.setDeleteTime(new Date(0));
        MbOrgEmployeeInfo oldEmployeeInfo = mbOrgEmployeeLoader.selectOneByRecord(record);
        if (oldEmployeeInfo != null) {
            failInfoList.add(addFaildInfo(SyncEmployeeInfoBo.SheetEnum.EMP.getIndex(),SyncEmployeeInfoBo.SheetEnum.EMP.getName(), employee.getLineNo(), employee.getLineNo(),OrganizationResponseCodeEnum.EMPLOYEE_PHONE_NO_EXIST.message()));
            throw new CorpBusinessException(OrganizationResponseCodeEnum.EMPLOYEE_PHONE_NO_EXIST);
        }
    }

    private void checkUidFromDb(SyncEmployeeInfoBo employee, List<SyncEmployeeCallBackRequestEntity.FailInfo> failInfoList) {
        MbOrgEmployeeInfo record = new MbOrgEmployeeInfo();
        record.setUid(employee.getUid());
        record.setDeleteTime(new Date(0));
        MbOrgEmployeeInfo oldEmployeeInfo = mbOrgEmployeeLoader.selectOneByRecord(record);
        if (oldEmployeeInfo != null) {
            failInfoList.add(addFaildInfo(SyncEmployeeInfoBo.SheetEnum.EMP.getIndex(),SyncEmployeeInfoBo.SheetEnum.EMP.getName(), employee.getLineNo(), employee.getLineNo(),OrganizationResponseCodeEnum.EMPLOYEE_UID_EXIST.message()));
            throw new CorpBusinessException(OrganizationResponseCodeEnum.EMPLOYEE_UID_EXIST);
        }
    }

    public void insertOrgEmployeeInfo(SyncEmployeeInfoBo employee) {
        MbOrgEmployeeInfo mbOrgEmployeeInfo = new MbOrgEmployeeInfo();
        mbOrgEmployeeInfo.setUid(employee.getUid());
        mbOrgEmployeeInfo.setName(employee.getName());
        mbOrgEmployeeInfo.setValid("T");
        mbOrgEmployeeInfo.setEmail(employee.getEmail());
        mbOrgEmployeeInfo.setAreaCode(employee.getCountryCode());
        mbOrgEmployeeInfo.setMobilePhone(employee.getMobilePhone());
        mbOrgEmployeeInfo.setGender(employee.getGender());
        if (StringUtils.isNotBlank(employee.getBirthday())) {
            mbOrgEmployeeInfo.setBirthday(DateUtil.stringToDate(employee.getBirthday(), "yyyy-MM-dd"));
        }
        if(StrUtil.isNotBlank(employee.getFirstName()) && StrUtil.isNotBlank(employee.getLastName())){
            mbOrgEmployeeInfo.setFirstEnName(employee.getFirstName());
            mbOrgEmployeeInfo.setLastEnName(employee.getLastName());
        }
        mbOrgEmployeeInfo.setFirstEnName(employee.getFirstName());
        mbOrgEmployeeInfo.setLastEnName(employee.getLastName());
        mbOrgEmployeeInfo.setNationCode(employee.getNationCode());
        mbOrgEmployeeInfo.setNationName(employee.getNationName());
        mbOrgEmployeeInfo.setNationality(employee.getNationality());
        mbOrgEmployeeInfo.setIsBackground(Boolean.FALSE);
        mbOrgEmployeeInfo.setDeleteTime(new Date(0));
        mbOrgEmployeeInfo.setEmployeeType(employee.getEmployeeType());

        NameInfoBo nameInfoBo = new NameInfoBo();
        nameInfoBo.setSurname(employee.getLastName());
        nameInfoBo.setGivenname(employee.getFirstName());
        nameInfoBo.setFullName(employee.getName());
        nameInfoBo.setNationality(employee.getNationality());
        if(StrUtils.checkNameInfo(nameInfoBo)){
            mbOrgEmployeeInfo.setNameInfo(JsonUtils.toJsonString(nameInfoBo));
        }
        orgEmployeeMapper.insertSelective(mbOrgEmployeeInfo);
    }

    public void updateOrgEmployeeInfo(SyncEmployeeInfoBo employee, MbOrgEmployeeInfo orgEmployeeInfo) {
        MbOrgEmployeeInfo mbOrgEmployeeInfo = ObjectUtils.copyProperties(orgEmployeeInfo, MbOrgEmployeeInfo.class);
        mbOrgEmployeeInfo.setName(employee.getName());
        mbOrgEmployeeInfo.setEmail(employee.getEmail());
        mbOrgEmployeeInfo.setGender(employee.getGender());
        if (StringUtils.isNotBlank(employee.getBirthday())) {
            mbOrgEmployeeInfo.setBirthday(DateUtil.stringToDate(employee.getBirthday(), "yyyy-MM-dd"));
        }
        if(StringUtils.isNotBlank(employee.getFirstName()) && StringUtils.isNotBlank(employee.getLastName())){
            mbOrgEmployeeInfo.setFirstEnName(employee.getFirstName());
            mbOrgEmployeeInfo.setLastEnName(employee.getLastName());
        }
        mbOrgEmployeeInfo.setFirstEnName(employee.getFirstName());
        mbOrgEmployeeInfo.setLastEnName(employee.getLastName());
        mbOrgEmployeeInfo.setNationCode(employee.getNationCode());
        mbOrgEmployeeInfo.setNationName(employee.getNationName());
        mbOrgEmployeeInfo.setNationality(employee.getNationality());
        mbOrgEmployeeInfo.setIsBackground(Boolean.FALSE);
        mbOrgEmployeeInfo.setUid(employee.getUid());
        mbOrgEmployeeInfo.setMobilePhone(employee.getMobilePhone());
        mbOrgEmployeeInfo.setEmployeeType(employee.getEmployeeType());
        NameInfoBo nameInfoBo = new NameInfoBo();
        nameInfoBo.setSurname(employee.getLastName());
        nameInfoBo.setGivenname(employee.getFirstName());
        nameInfoBo.setFullName(employee.getName());
        nameInfoBo.setNationality(employee.getNationality());
        if(StrUtils.checkNameInfo(nameInfoBo)){
            mbOrgEmployeeInfo.setNameInfo(JsonUtils.toJsonString(nameInfoBo));
        }
        orgEmployeeMapper.updateEmployeeByUid(mbOrgEmployeeInfo);
    }

    /**
     * 导入时根据 business和postName更新人员身份表
     *
     * @param employee
     */
    public void updateOrgInfoAndPost(SyncEmployeeInfoBo employee) {
        String businessCode = employee.getBusinessCode();
        String postName = employee.getPostName();
        Long postId = employee.getPostId();

        List<MbPostInfo> postInfos = Objects.isNull(postId) ?
                (StringUtils.isBlank(postName) ? new ArrayList<>() : postService.findByName(postName)) :
                Lists.newArrayList(postService.find(employee.getPostId()));
        if (StringUtils.isNotBlank(businessCode)) {
            MbOrgInfo mbOrgInfo = organizationInfoService.findByBusinessCode(businessCode);
            if (StringUtils.isBlank(employee.getFirstCorgId())) {
                return;
            }
            MbPostInfo postInfo = Optional.ofNullable(selectPostByOrgId(postInfos, employee.getFirstCorgId())).orElse(new MbPostInfo());
            // 查询员工状态
            MbUserOrgRelation mbUserOrgRelation = mbUserOrgRelationMapper.selectOneByUid(employee.getUid());
            userOrgRelationMapper.deleteByUid(employee.getUid());
            insertUserOrgRelation(mbUserOrgRelation,employee, mbOrgInfo, postInfo.getId());
            //更新人员新鲜度表组织数据
            freshPassengerService.batchUpdateEmployeeOrg(Lists.newArrayList(employee.getUid()), mbOrgInfo.getOrgId());
        } else {
            if (CollectionUtils.isNotEmpty(postInfos)) {
                List<MbUserOrgRelation> mbUserOrgRelations = Optional.ofNullable(userOrgRelationMapper.listByUid(employee.getUid())).orElse(new ArrayList<>());
                for (MbUserOrgRelation mbUserOrgRelation : mbUserOrgRelations) {
                    MbPostInfo postInfo = selectPostByOrgId(postInfos, employee.getFirstCorgId());
                    if (postInfo != null) {
                        userOrgRelationMapper.updatePostIdById(postInfo.getId(), mbUserOrgRelation.getId());
                        return;
                    }
                }
            }
        }
    }

    public void insertUserOrgRelation(MbUserOrgRelation mbUserOrgRelation,SyncEmployeeInfoBo employee, MbOrgInfo defaultOrgInfo, Long postId) {
        MbUserOrgRelation mbUserOrgRelationDB = new MbUserOrgRelation();
        mbUserOrgRelationDB.setUid(employee.getUid());
        mbUserOrgRelationDB.setOrgId(defaultOrgInfo.getOrgId());
        mbUserOrgRelationDB.setPostId(postId);
        mbUserOrgRelationDB.setDeleteTime(new Date(0));
        mbUserOrgRelationDB.setManageUid(employee.getManageUid());
        if(mbUserOrgRelation==null){
            mbUserOrgRelationDB.setStatus(StaffStatusEnum.normal.getCode());
            mbUserOrgRelationDB.setIsLeader(0);
            mbUserOrgRelationDB.setVipLevel(0);
        } else {
            mbUserOrgRelationDB.setStatus(mbUserOrgRelation.getStatus());
            mbUserOrgRelationDB.setIsLeader(mbUserOrgRelation.getIsLeader());
            mbUserOrgRelationDB.setVipLevel(mbUserOrgRelation.getVipLevel());
        }
        userOrgRelationService.save(mbUserOrgRelationDB);
    }

    private MbPostInfo selectPostByOrgId(List<MbPostInfo> postInfos, String orgId) {
        return postInfos.stream().filter(i -> i.getOrgId().equals(orgId)).findFirst().orElse(null);
    }


    public void insertUserLogin(SyncEmployeeInfoBo employee) {
        MbUserLogin addUserLogin = new MbUserLogin();
        addUserLogin.setAccountName(employee.getCountryCode() + employee.getMobilePhone());
        addUserLogin.setUid(employee.getUid());
        addUserLogin.setPwd(Md5Util.getDeepMd5Msg(employee.getUid(), employee.getPassword()));
        addUserLogin.setUserName(employee.getName());
        addUserLogin.setBgUser(0);
        addUserLogin.setCountryCode(employee.getCountryCode());
        addUserLogin.setPhoneNum(employee.getMobilePhone());
        addUserLogin.setEmail(employee.getEmail());
        addUserLogin.setStatus(1);
        userLoginService.create(addUserLogin);
    }

    public void insertUserLoginWithSms(SyncEmployeeInfoBo employee) {

        insertUserLogin(employee);

        log.info("insertUserLoginWithSms employee:{}", employee);

        // 发送短信
        Boolean avalibleSendMsg =  abTestUtil.getBooleanAbTestResultWithAuto("sendSms", TenantContext.getTenantId());
        if (avalibleSendMsg) {
            Map<String, Object> vars = new HashMap<>();
            vars.put("phone", employee.getMobilePhone());
            vars.put("pwd", employee.getPassword());
            msgService.sendAliyunTemplateMsg(MsgBizType.EMPLOYEE_INIT_PHONE_AND_PWD,vars, employee.getMobilePhone(), employee.getCountryCode());
        }

    }

    public void updateUserLogin(SyncEmployeeInfoBo employee) {
        MbUserLogin getUserLogin = userLoginService.getByUid(employee.getUid());
        getUserLogin.setUserName(employee.getName());
        getUserLogin.setEmail(employee.getEmail());
        userLoginService.update(getUserLogin);
    }

    public MbOrgInfo getOrgInfoByOrgId(String orgId) {
        return organizationInfoService.findByOrgId(orgId);
    }

    public void insertUserOrgRelation(SyncEmployeeInfoBo employee, MbOrgInfo defaultOrgInfo, Long postId) {
        MbUserOrgRelation mbUserOrgRelation = new MbUserOrgRelation();
        mbUserOrgRelation.setUid(employee.getUid());
        mbUserOrgRelation.setOrgId(defaultOrgInfo.getOrgId());
        mbUserOrgRelation.setIsLeader(0);
        mbUserOrgRelation.setPostId(postId);
        mbUserOrgRelation.setStatus(1);
        mbUserOrgRelation.setVipLevel(0);
        mbUserOrgRelation.setDeleteTime(new Date(0));
        mbUserOrgRelation.setManageUid(employee.getManageUid());
        userOrgRelationService.save(mbUserOrgRelation);
    }


    public void insertFreshPassenger(SyncEmployeeInfoBo employee, MbOrgInfo defaultOrgInfo) {
        String orgId = "";
        if (StringUtils.isNotBlank(employee.getBusinessCode())) {
            MbOrgInfo mbOrgInfo = organizationInfoService.findByBusinessCode(employee.getBusinessCode());
            orgId = Objects.isNull(mbOrgInfo) ? defaultOrgInfo.getOrgId() : mbOrgInfo.getOrgId();
        } else {
            orgId = defaultOrgInfo.getOrgId();
        }

        MbFreshPassenger mbFreshPassenger = new MbFreshPassenger();
        mbFreshPassenger.setEmployeeUid(employee.getUid());
        mbFreshPassenger.setOrgId(orgId);
        mbFreshPassenger.setName(employee.getName());
        String enName = "";
        if (StringUtils.isNotBlank(employee.getFirstName()) || StringUtils.isNotBlank(employee.getLastName())) {
            enName = (StringUtils.isNotBlank(employee.getFirstName()) ? employee.getFirstName() : "") + "/" + (StringUtils.isNotBlank(employee.getLastName()) ? employee.getLastName() : "");
        }
        mbFreshPassenger.setEnName(StringUtils.isEmpty(enName) ? null : enName);
        mbFreshPassenger.setValid(false);
        mbFreshPassenger.setIsDeleted(false);
        freshPassengerService.save(mbFreshPassenger);

        MbFreshPassengerRelation mbFreshPassengerRelation = new MbFreshPassengerRelation();
        mbFreshPassengerRelation.setEmployeeFlag(1);
        mbFreshPassengerRelation.setFreshUid(employee.getUid());
        mbFreshPassengerRelation.setFreshTime(new Date());
        mbFreshPassengerRelation.setIsDeleted(false);
        mbFreshPassengerRelation.setUid(employee.getUid());
        mbFreshPassengerRelation.setDatachangeLasttime(new Date());
        mbFreshPassengerRelation.setDatachangeCreatetime(new Date());
        freshPassengerRelationService.save(mbFreshPassengerRelation);
    }

    public void insertCardInfo(SyncEmployeeInfoBo employee, List<SyncEmployeeCallBackRequestEntity.FailInfo> failInfoList) {
        if (CollectionUtils.isNotEmpty(employee.getCardInfoList())) {
            organizationUserIdCardService.deleteByEmployeeUid(employee.getUid());
            employee.getCardInfoList().forEach(cardType -> {
                List<MbOrgUserIdcard> mbOrgUserIdcards = organizationUserIdCardService
                    .findByTypeAndNo(Integer.valueOf(cardType.getCardType()), cardType.getCardNo(), false);
                if (!CollectionUtils.isEmpty(mbOrgUserIdcards)) {
                    failInfoList.add(addFaildInfo(SyncEmployeeInfoBo.SheetEnum.CARD.getIndex(),SyncEmployeeInfoBo.SheetEnum.CARD.getName(),cardType.getLineNo(), employee.getLineNo(),MessageFormat.format("{0}证件号重复,请检查", cardType.getCardNo())));
                    throw new CorpBusinessException(OrganizationResponseCodeEnum.EMPLOYEE_IMPORT_FAILED);
                }
            });

            List<MbOrgUserIdcard> userIdcards = new ArrayList<>();
            employee.getCardInfoList().forEach(item -> {
                MbOrgUserIdcard mbOrgUserIdcard = new MbOrgUserIdcard();
                mbOrgUserIdcard.setCardNo(item.getCardNo());
                mbOrgUserIdcard.setCardType(Integer.valueOf(item.getCardType()));
                mbOrgUserIdcard.setDeleteTime(new Date(0));
                mbOrgUserIdcard.setEmployeeUid(employee.getUid());
                mbOrgUserIdcard.setTimeLimit(DateUtil.stringToDate(item.getTimeLimit(), "yyyy-MM-dd"));
                mbOrgUserIdcard.setPlaceOfIssue(item.getPlaceOfIssue());
                userIdcards.add(mbOrgUserIdcard);
            });
            organizationUserIdCardService.batchSave(userIdcards);
        }
    }

}
